Use subclasses of Net::HTTPRequest instead of Net::HTTPGenericRequest #647
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Fixes a problem with
net-http-persistent
adapter that is checking the subclasses ofNet::HTTPRequest
for idempotence support.Instead of directly instantiating
Net::HTTPGenericRequest
, use the appropriateNet::HTTPRequest
subclass.We stumbled upon this situation at @catawiki when we switched our internal API client to
faraday
(backed bynet-http-persistent
). Whenever we reloaded ournginx
instances we sawNet::HTTP::Persistent::Error: too many connection resets (due to end of file reached - EOFError)
exception being thrown to the application level, due to the sockets being closed.It took a lot of trial and error and quite some digging to figure out what's going on even tho we haven't changed the underlying http library (
net-http-persistent
). There are a couple of reports online that might to be related to this issue (sparklemotion/mechanize#123, drbrain/net-http-persistent#37) and a couple of gems such aselasticsearch-ruby
might be affected by this issue depending on the configuration.The problem is that
faraday
is creating a class ofNet::HTTPGenericRequest
for thenet-http
adapter. Yet thenet-http-persistent
gem (whosefaraday
adapter implementation is subclassing thenet-http
adapter) is expecting a Net::HTTPRequest subclass. Based on the class it decides whether a request is idempotent.If a request is idempotent then it automatically retries the request once.
As a temporary workaround we used the
Faraday::Request::Retry
middleware as follows:(
max
is set intentionally to1
)The idea for the approach in this PR is liberally taken from mechanize.
Note: this change is breaking the specs. In Ruby 1.8, 1.9.3, 2.1 the
Net::Http::Options
is marked as not returning a body. This has been fixed in Ruby 2.2, even tho OPTIONS may have a request body since RFC2616. Previously the specs passed because the check was:head != env[:method]
. So I'm not sure what's the appropriate approach for the specs or if this change is acceptable overall (the behaviour now depends on the Ruby version?).I'll openI've opened PR #83 tonet-http-persistent
as well to use#method
instead of checking the class hierarchy.@mislav what do you think?